﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using log4net;
using System.Threading;
using DWH.Data;
using DWH.Utils;

namespace DWH.PP.Push
{
    public class PageTorrentDownloadWorker : PageAttachmentDownloadWorkerBase
    {
        private ILog logger;
        private static int WorkInstanceID = 1;
        
        public string TorrentType { get; set; }

        public PageTorrentDownloadWorker()
        {
            logger = LogManager.GetLogger(typeof(PageTorrentDownloadWorker));
        }

        public override void Initialize()
        {
            base.Initialize();
                       
            TorrentType = ExtendData[DWHConstants.KEY_WORKER_TORRENT_TYPE];
        }

        public override void DoWork()
        {
            int thisWorkerInstanceID = WorkInstanceID++;

            logger.InfoFormat("Worker {0}-ID:{1} start to work", TaskName, thisWorkerInstanceID);

            while (true)
            {
                if (ProcessingCollection.Count == 0)
                {
                    logger.InfoFormat("items finished, Worker {0} try to add items", thisWorkerInstanceID);

                    AddProcessingItems();
                }

                PageAttachment item = null;

                try
                {
                    item = ProcessingCollection.Take();

                    logger.InfoFormat("Worker {0}-ID:{1} ,processing item: {2}", TaskName, thisWorkerInstanceID, item.PageAttachmentUrl);
                    ProcessPageAttachment(item, thisWorkerInstanceID);

                }
                catch (Exception ex)
                {
                    logger.ErrorFormat("Worker {0}-ID:{1} , Exception when processing item {2}, ex: {3}", TaskName, thisWorkerInstanceID, item.PageAttachmentUrl, ex.ToString());
                }

                Thread.Sleep(1 * 1000);
            }
        }

        public void AddProcessingItems()
        {
            //ProcessingCollection.Add("");           
            List<PageAttachment> atts = null;

            while (atts == null || atts.Count == 0)
            {
                logger.InfoFormat("no new attachments in database, sleep for 5 minutes to continue");
                DWHHelper.SimulateUserClickInterval(5 * 60, false);

                atts = DWHDBHelper.GetPageAttachmentByAttachmentType(TorrentType);
            }

            foreach (PageAttachment att in atts)
            {
                ProcessingCollection.Add(att);
            }

            logger.InfoFormat("add PageAttachments to process, count:{0}", atts.Count);
        }

        public void ProcessPageAttachment(PageAttachment att, int thisWorkerInstanceID)
        {
            try
            {
                switch (TorrentType)
                {
                    case DWHConstants.ATTACHMENT_TYPE_TORRENT_JIANDOWN:
                        DWHHelper.DownloadTorrentJandown(att.PageAttachmentUrl, att.StoredPath);
                        break;

                    case DWHConstants.ATTACHMENT_TYPE_TORRENT_BFXZW:
                        DWHHelper.DownloadTorrentCLBfxzw(att.PageAttachmentUrl, att.StoredPath);
                        break;

                    case DWHConstants.ATTACHMENT_TYPE_TORRENT_UHOPEFIND:
                        DWHHelper.DownloadTorrentUhopefind(att.PageAttachmentUrl, att.StoredPath);
                        break;

                    case DWHConstants.ATTACHMENT_TYPE_TORRENT_RMDOWN:
                        DWHHelper.DownloadTorrentCLRmdown(att.PageAttachmentUrl, att.StoredPath);
                        break;

                    default:
                        logger.ErrorFormat("unsupported torrent type:{0}", TorrentType);
                        break;
                }

                DWHDBHelper.UpdatePageAttachmentDownloadStatus(att.ID, TaskName, DateTime.Now, PageAttachmentDownloadStatus.Downloaded);
            }
            catch (Exception ex)
            {
                logger.ErrorFormat("Worker {0}-ID:{1} , Exception when saving item {2}, ex: {3}", TaskName, thisWorkerInstanceID, att.PageAttachmentUrl, ex.ToString());
            }
        }
    }
}
